﻿using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Threading;

namespace SpriteTool
{
    public partial class Form1 : Form
    {
        TextBox[] browseBoxes;

        public Form1()
        {
            InitializeComponent();

            //initialize our textboxes
            browseBoxes = new TextBox[8];
            browseBoxes[0] = txtFile1;
            browseBoxes[1] = txtFile2;
            browseBoxes[2] = txtFile3;
            browseBoxes[3] = txtFile4;
            browseBoxes[4] = txtFile5;
            browseBoxes[5] = txtFile6;
            browseBoxes[6] = txtFile7;
            browseBoxes[7] = txtFile8;
        }

        /// <summary>
        /// Gets the files you browse for and sets there filenames
        /// into the appropriate text box for later use
        /// </summary>
        private void btnBrowse_Click(object sender, EventArgs e)
        {
            int index = int.Parse((sender as Button).AccessibleName);
            string text = string.Empty;
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                foreach (string file in openFileDialog1.FileNames)
                    text += (file + ",");
            }
            browseBoxes[index].Text = text;
        }

        /// <summary>
        /// Will clear the text box of files
        /// </summary>
        private void btnClear_Click(object sender, EventArgs e)
        {
            int index = int.Parse((sender as Button).AccessibleName);
            browseBoxes[index].Text = string.Empty;
        }

        /// <summary>
        /// Clears all the text boxes
        /// </summary>
        private void btnClearAll_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < browseBoxes.Length; i++)
                browseBoxes[i].Text = string.Empty;
        }

        /// <summary>
        /// Will create and save the images accordingly
        /// </summary>
        private void btnGo_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(browseBoxes[0].Text))
            {
                MessageBox.Show("You are missing pictures");
                return;
            }

            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                // Create the progress form window
                ProgressForm progressForm = new ProgressForm(SaveImage);
                progressForm.ShowDialog();
            }
        }

        /// <summary>
        /// Creates and saves the image while loading the progress bar
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SaveImage(object sender, EventArgs e)
        {
            // get our progress form from the sender
            ProgressForm progress = sender as ProgressForm;
            progress.SetStatus("Loading");
            progress.SetProgress(0);

            // load our files from the text boses
            List<List<string>> files = new List<List<string>>();
            for (int i = 0; i < browseBoxes.Length; i++)
                files.Add(GetFiles(browseBoxes[i]));

            // get the number of animations and columns
            int numberOfColumns = files[0].Count;
            int numberOfAnimations = 0;
            int numberOfImages = 0;
            foreach (List<string> list in files)
            {
                numberOfColumns = Math.Max(numberOfColumns, list.Count);
                numberOfImages += list.Count;
                if (list.Count > 0)
                    numberOfAnimations++;

                else
                    break;
            }

            int offset;
            int xOffset;
            int additionX;
            int additionY;

            // set if we need to add an offset
            if (cbPixelBorder.Checked)
            {
                offset = 1;
                xOffset = 1;
                additionX = numberOfColumns * 2;
                additionY = numberOfAnimations * 2;
            }
            else
            {
                offset = 0;
                xOffset = 0;
                additionY = numberOfAnimations - 1;
                additionX = 0;
            }

            Bitmap firstFile = (Bitmap)Image.FromFile(files[0][0].ToString());

            // used for setting the progress of the progress bar
            float percent = 0;
            progress.SetStatus("Loading Images");

            // this is the end result of adding all the images together
            Bitmap endFile = new Bitmap(numberOfColumns * firstFile.Width + additionX,
                numberOfAnimations * firstFile.Height + additionY);

            //try
            //{

                // loop through all of our images and add them into the overall image
                foreach (List<string> fileLists in files)
                {
                    // if there are no images break out
                    if (fileLists.Count < 1)
                        break;

                    List<Bitmap> frames = new List<Bitmap>();

                    // create a list of images from our filenames
                    foreach (string file in fileLists)
                    {
                        if (string.IsNullOrEmpty(file))
                            break;

                        frames.Add((Bitmap)Bitmap.FromFile(file));
                        percent += 50 / numberOfImages;
                        progress.SetProgress((int)percent);
                    }

                    progress.SetStatus("Creating Image");

                    // loop through our images
                    foreach (Bitmap b in frames)
                    {
                        // loop through each point
                        for (int x = 0; x < b.Width; x++)
                        {
                            for (int y = 0; y < b.Height; y++)
                            {
                                // get the color of that point
                                Color color = b.GetPixel(x, y);

                                // if the alpha is zero set the color to transparent
                                if (color.A == 0f)
                                    color = Color.Transparent;

                                // set the color of the endfile to the color of the current image
                                int setX = x + (firstFile.Width * frames.IndexOf(b)) + xOffset;
                                int setY = y + offset;
                                endFile.SetPixel(setX, setY, color);
                            }
                        }

                        // set progress
                        percent +=50 / numberOfImages;
                        progress.SetProgress((int)percent);

                        // if we want the border we need to add 2 to the offset each time
                        if (cbPixelBorder.Checked)
                            xOffset += 2;
                    }

                    // we need to reset this for each row of images if we want the border
                    if (cbPixelBorder.Checked)
                    {
                        xOffset = 1;
                        offset += firstFile.Height + 2;
                    }
                    else
                    {
                        offset += firstFile.Height;
                    }
                }

                // finally save our image
                endFile.Save(saveFileDialog1.FileName + ".png", ImageFormat.Png);

                progress.SetStatus("Completed");
                progress.Completed();
            //}
            //catch (Exception exc)
            //{
            //    progress.Close();
            //    MessageBox.Show(string.Format("{0}\n{1}", exc.Message, exc.Source), "Error");
            //}
        }

        /// <summary>
        /// Gets the list of file names from our text boxes
        /// </summary>
        private List<string> GetFiles(TextBox textBox)
        {
            List<string> temp = new List<string>();
            foreach (string f in textBox.Text.Split(','))
                temp.Add(f);

            // there is a trailing blank be sure to delete it
            temp.Remove("");
            return temp;
        }
    }
}
